/*
 * @Author: czy
 * @Date: 2021-04-04 22:39:40
 * @LastEditTime: 2021-05-02 07:47:59
 */
#include "uart.h"
#include "vga.h"
#include "mystdio.h"
#include "mystring.h"

#define BUFSIZE 400

/**
 * @description: Formats a string in the specified format, and output on VGA and serial port.
 * @param buf   The first address of the buffer.
 * @param fmt   Format string.
 * @param args  Parameter list.
 * @return The length of the string in the buffer.
 */
int myPrint(char *buf, int color, const char *format, va_list args)
{
    int n;
    strzero(buf, BUFSIZE);
    n = vsprintf(buf, format, args);
    append2screen(buf, color);
    uart_put_chars(buf);
    return n;
}

// Kernel version.
char kBuf[BUFSIZE];
int myPrintk(int color, const char *format, ...)
{
    int n;
    va_list args;
    va_start(args, format);
    n = myPrint(kBuf, color, format, args);
    set_boundary();
    va_end(args);
    return n;
}

int myprintk(const char *format, ...)
{
    int n;
    va_list args;
    va_start(args, format);
    n = myPrint(kBuf, WHITE, format, args);
    set_boundary();
    va_end(args);
    return n;
}

// User version.
char uBuf[BUFSIZE];
int myPrintf(int color, const char *format, ...)
{
    int n;
    va_list args;
    va_start(args, format);
    n = myPrint(uBuf, color, format, args);
    va_end(args);
    return n;
}

int myprintf(const char *format, ...)
{
    int n;
    va_list args;
    va_start(args, format);
    n = myPrint(uBuf, WHITE, format, args);
    va_end(args);
    return n;
}

/**
 * @description: Outputs message at a specified location, such as the current time. 
 *                  When the output is finished, the cursor returns to its original position.
 * @param position  LEFT if 1 else RIGHT.
 * @param color     Output color.
 * @param msg       Message.
 */
void message(int position, int color, char *format, ...)
{
    char str[100] = "";
    va_list args;
    va_start(args, format);
    vsprintf(str, format, args);
    show_message(position, color, str);
}

/**
 * @description: Cursor offset.
 * @param offset    Offset.
 */
void cursor_offset(int offset)
{
    vga_offset(offset);
    uart_offset(offset);
}

/**
 * @description: Output a character on VGA and UART.
 * @param ch    Character to be output.
 */
void myPutchar(unsigned char ch)
{
    char c = vga_put_char(ch, WHITE);
    uart_put_char(c);
}

/**
 * @description: Get a character from UART.
 */
unsigned char myGetchar(void)
{
    return uart_get_char();
}

/**
 * @description: Clear vga.
 */
void clear(void)
{
    clear_screen();
}
